/*
 * CS_BLACKSMITH_REFINE.cpp
 *
 *  Created on: 2013. 5. 27.
 *      Author: mega@gamevil.com
 */

#include "../../Command.h"
#include "../../User.h"
#include "../../NLogic/Item.h"
#include "../../NUtil/Utils.h"
#include "../../NLogic/Bag.h"
#include "../../NLogic/DailyMission.h"
#include "../../NLogic/VirtualCurrency.h"
#include "../../NResource/Static.h"
#include "../../GameLog.h"

namespace ProjectZ { namespace NCommand {

static void SendPacket_CS_BLACKSMITH_REFINE(User * pUser, uint16_t res, uint64_t item_seq, char bag_type) {

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << res << item_seq << bag_type;
	pAck->MakePacket(CMD_SC_BLACKSMITH_REFINE);
	pUser->Send(pAck);
}

void Command::CS_BLACKSMITH_REFINE(User * pUser, ::Network::Packet * pPacket)
{
/*	// 제련
	ZNO_CS_BLACKSMITH_REFINE //0x2202
	{
		u8	u8refine_type;		// 제련 타입 (0: 일반, 1: 고급)
		u64	u64item_seq;		// 아이템 시컨스
		u8	u8bag_type;
	}

	// 제련 응답
	ZNO_SC_BLACKSMITH_REFINE //0x2203
	{
		s16	s16_ack;		// 제련 결과 (성공, 실패) : 실패시 아이템 삭제 대기?.. (350 : 제련 실패, 351 : 제련 MAX)
		u64	u64item_seq;		// 아이템 시컨스
		u8	u8bag_type;
	}*/

	PREPARE_PACKET;

	char		refineType	= 0;	// 0:일반 1:고급
	uint64_t	itemSeq		= 0;
	char		bagType		= 0;

	*pPacket >> refineType >> itemSeq >> bagType;

	if (refineType < 0 || refineType > 1)
	{
		DEBUGLOG("CS_BLACKSMITH_REFINE : INVALID refineType=%d", refineType);
		return;
	}

	NLogic::Bag * pBag = pUser->GetBag(static_cast<INVEN_BAG_TYPE>(bagType));

	if (pBag == NULL)
	{
		DEBUGLOG("CS_BLACKSMITH_REFINE : pBag is NULL!!");
		return;
	}

	NLogic::Item * pItem = pBag->GetItem(itemSeq);

	if (pItem == NULL)
	{
		DEBUGLOG("CS_BLACKSMITH_REFINE : pItem is NULL!!");
		return;
	}

	if (false == NResource::Static::Instance().GetItemResource()->isEquip(pItem->GetData()))
	{
		DEBUGLOG("CS_BLACKSMITH_REFINE : INVALID SHEET TYPE=%d", pItem->GetData().sub_type);
		return;
	}

	// 제련 단계 확인
	if (pItem->GetData().cur_refine_step >= pItem->GetData().max_enhance_step)
	{
		SendPacket_CS_BLACKSMITH_REFINE(pUser, ACK_ITEM_REFINE_MAX, itemSeq, bagType);
		return;
	}

	// 제련 가격 계산
	NResource::BalanceData * pBalance = NResource::Static::InstancePtr()->GetBalance()->GetBalancePtr(pUser);
	if (NULL == pBalance)
	{
		DEBUGLOG("CS_BLACKSMITH_REFINE : pBalance is NULL!");
		return;
	}

	int constValue	= 0;
	int refineGold	= 0;
	int refineZen	= 0;
	int nextStep	= pItem->GetData().cur_refine_step + 1;

	int use_goods = 0;
	if (1 == refineType)
	{
		use_goods = 2;
		constValue = pBalance->GetValue(EM_REFINE_ZEN_PRICE_CONST);
		refineZen = nextStep * constValue;
		if (pUser->GetVirtualCurrency()->GetZen() < refineZen)
		{
			SendPacket_CS_BLACKSMITH_REFINE(pUser, ACK_NOT_ENOUGH_ZEN, itemSeq, bagType);
			return;
		}
	}
	else
	{
		use_goods = 1;
		constValue = pBalance->GetValue(EM_REFINE_GOLD_PRICE_CONST);
		refineGold = (((int)pow(nextStep, 2) / (constValue + 1)) * 500 + 500) * 2;
		if (static_cast<int>(pUser->GetCharacterInfo().gold) < refineGold)
		{
			SendPacket_CS_BLACKSMITH_REFINE(pUser, ACK_NOT_ENOUGH_GOLD, itemSeq, bagType);
			return;
		}
	}

	NResource::ItemRefineData::Flyweight * pFly =
			NResource::Static::InstancePtr()->GetItemRefine()->GetFly(pUser);
	if (NULL == pFly)
	{
		DEBUGLOG("CS_BLACKSMITH_REFINE : pFly is NULL!!");
		return;
	}

	// 아이템 제련
	int refineRate = 0;

	switch (pItem->GetData().cur_refine_step)
	{
	case 0 : refineRate = pFly->_REFINE1; break;
	case 1 : refineRate = pFly->_REFINE2; break;
	case 2 : refineRate = pFly->_REFINE3; break;
	case 3 : refineRate = pFly->_REFINE4; break;
	case 4 : refineRate = pFly->_REFINE5; break;
	case 5 : refineRate = pFly->_REFINE6; break;
	case 6 : refineRate = pFly->_REFINE7; break;
	case 7 : refineRate = pFly->_REFINE8; break;
	case 8 : refineRate = pFly->_REFINE9; break;
	case 9 : refineRate = pFly->_REFINE10; break;
	case 10 : refineRate = pFly->_REFINE11; break;
	case 11 : refineRate = pFly->_REFINE12; break;
	case 12 : refineRate = pFly->_REFINE13; break;
	case 13 : refineRate = pFly->_REFINE14; break;
	case 14 : refineRate = pFly->_REFINE15; break;
	}

	// 고급 제련 확률 계산
	if (1 == refineType)
	{
		refineRate = (refineRate * 3) / 2 + 10;
	}

	int randRate = rand() % 1000;

	// 아이템 제련 실패
	if (randRate > refineRate)
	{
		SendPacket_CS_BLACKSMITH_REFINE(pUser, ACK_ITEM_REFINE_FAIL, itemSeq, bagType);
		NGameLog::LogItemInfo(pUser, BLACKSMITH_REFINE_ITEM, 0, use_goods, pItem);
	}
	else
	{
		// 제련 단계 증가
		pItem->GetData().cur_refine_step = nextStep;

		// 기본 효과값 상승
		int newValue = NUtil::AddPercentage(pItem->GetData().eff_value[0], pBalance->GetValue(EM_REFINE_STATS_ENHANCE_RATE));

		if (newValue == pItem->GetData().eff_value[0])
			pItem->GetData().eff_value[0] += 1;
		else
			pItem->GetData().eff_value[0] = newValue;

		pItem->UpdateDatabaseItemInfo();

		SendPacket_CS_BLACKSMITH_REFINE(pUser, ACK_OK, itemSeq, bagType);
		NGameLog::LogItemInfo(pUser, BLACKSMITH_REFINE_ITEM, 1, use_goods, pItem);
	}

	// VC 처리
	if (1 == refineType)
	{
		NLogic::NFunction::VCProcess(pUser, EM_VCINDEX_ITEM_REFINE, refineZen);
	}
	else
	{
		NLogic::NFunction::ModifyGold(pUser, refineGold * -1);
		NGameLog::LogGoldInfo(pUser, REFINE, refineGold * -1);
	}

	// 일일 미션
	NLogic::DailyMission * pDailyMission = pUser->GetDailyMission();
	if (NULL != pDailyMission)
	{
		pDailyMission->MissionComplete(NLogic::DailyMission::MissionType::MISSION5);
	}
}

} /*NCommand*/ } /*ProjectZ*/
